<?php

class UrlRouter {

	private $_xml;
	private $_schemaFile;
	
	private $_urlMap = array();
	
	private $_firstRun = true;
	
	public function __construct($schemaFile) {
	
		// Set the schemafile
		$this->_schemaFile = $schemaFile;
		
		// Start initializing the routing
		$this->_init();
	}
	
	private function _init() {
	
		// Check if the schemafile exists
		if (!file_exists($this->_schemaFile)) {
			
			//throw new Exception('Schemafile does not exist.');
			die('Schemafile does not exist.');
		}
		
		// Load the schemafile
		$this->_xml = new SimpleXmlElement($this->_schemaFile, false, true);
		
		// Map the xml content to an array
		$this->_mapToArray($this->_xml);
	}
	
	private function _mapToArray($nodes, $prefix='') {
	
		// Walk through all nodes
		foreach($nodes as $node) {
		
			// Set a temporary array to hold the content
			$tmpArray = array();
			
			// Get the name and the url
			$nodeName = $prefix.$node->getName();
			$nodeUrl = false;
			
			// Check for url or redirect
			if (isset($node['url']) && !empty($node['url'])) {
			
				$nodeUrl = trim($node['url']);
			} elseif (isset($node['redirect']) && !empty($node['redirect'])) {
			
				$nodeUrl = $this->_getRedirectTarget($node, $node['redirect']);
			} else {
			
				// No url was found, error in url map syntax
				// throw new Exception('Node without target url');
				die('Node without target url');
			}
			
			// Set default?
			if ($this->_firstRun || isset($node['default'])) {
				
				// Set the default url
				$tmpArray['_default']['url'] = $nodeUrl;
				
				// Toggle firstRun flag
				$this->_firstRun = false;
			}
			
			// Add the current node to the array
			$tmpArray[$nodeName] = array(
				'url' => $nodeUrl,
				'ajax' => (bool) (isset($node['ajax']) && !empty($node['ajax']))
			);
			
			// Merge the current array
			$this->_urlMap = array_merge_recursive($this->_urlMap, $tmpArray);
			
			// Eventually add map of children if possible
			if (count($node->children())) {
				
				// Set prefix
				$tmpPrefix = $prefix.$nodeName.'/';
				$this->_mapToArray($node, $tmpPrefix);
			}
		}
	}
	
	private function _getRedirectTarget($node, $type) {
	
		// Set correct target by type
		switch ($type) {
		
			case 'first':
				// There has to be a child with a url
				if (!count($node->children())) {
				
					// throw new Exceoption('No children to redirect to');
					die('No children to redirect to');
				}
				
				// Loop through all children and get the first possible URL
				foreach ($node->children() as $childNode) {
				
					if (isset($childNode['url']) && !empty($childNode['url'])) {
					
						return trim($childNode['url']);
					}
				}
				
				// If this is reached, no child with a URL exists
				// throw new Exceoption('No children to redirect to');
				die('No children to redirect to');
				
				break;
			
			// If none existing type, it should be a URL
			default:
				return $type;
				break;
		}
	}
	
	public function getCurrentRoute() {
	
		// Get the current url
		$url = new Url(false, false, false);
		$currentUrl = $url->getUrl();
		
		// if empty, return default
		if (empty($currentUrl) && isset($this->_urlMap['_default']) && isset($this->_urlMap['_default']['url'])) {
			
			$tmpUrl = $this->_urlMap['_default']['url'];
		} elseif (!empty($currentUrl) && isset($this->_urlMap[$currentUrl]) && isset($this->_urlMap[$currentUrl]['url'])) {
		
			$tmpUrl = $this->_urlMap[$currentUrl]['url'];
		} else {
		
			// throw new Exception('Page not found');
			die('Page not found');
		}
		
		return new Url($tmpUrl);
	}

}